<?php
/**
 * Simple database class
 * Example :
 * $db = Database::getInstance();
 * $db->query("SELECT ...");
 *
 * @author Matt Pike
 */
class Database{
	private static $instance = null;


	/**
	 * Actual connection
	 * @var unknown_type
	 */
	private $connection = null;
	/**
	 * Dont instantiate directly, use getInstance() then
	 */
	private function __construct(){
		$this->connection = mysql_connect(SiteConfig::$dbHost,SiteConfig::$userName,SiteConfig::$userPassword);
		mysql_select_db(SiteConfig::$dbName);
		if(!$this->connection){
			throw new Exception("Unable to connect to database",93845345);
		}
	}

	/**
	 * Returns singleton instance of database
	 *
	 * @return Database
	 */
	public static function getInstance(){
		if(self::$instance){
			return self::$instance;
		}else{
			return new self();
		}
	}

	/**
	 * Query DB and return result set as array
	 *
	 * @param string $q
	 * @return array associative
	 */
	public function query($q){
		//Execute query & return result array
		$db = Database::getInstance();
		$result = mysql_query($q,$db->connection);
		$error = mysql_error($db->connection);
		if($error){
			throw new Exception("Mysql Error #".mysql_errno($db->connection).": ".$error);
		}
		if($result){
			$rows = mysql_fetch_array($result);
			return $rows;
		}
	}

	/**
	 * Query DB and return result as single value
	 *
	 * @param string $q
	 * @return array associative
	 */
	public function querySingle($q){
		//Execute query & return result array
		$db = Database::getInstance();
		$result = mysql_query($q,$db->connection);
		$error = mysql_error($db->connection);
		if($error){
			throw new Exception("Mysql Error #".mysql_errno($db->connection).": ".$error);
		}
		if($result){
			$row = mysql_fetch_row($result);
			return $row[0];
		}
	}

	/**
	 * Call the target SP
	 *
	 * @param string $targetSP
	 * @param array $params
	 * @return array $returnedRows
	 */
	public function callSP($targetSP, array $params){
		//Connect to DB
		$link = mysqli_connect(SiteConfig::$dbHost, SiteConfig::$userName, SiteConfig::$userPassword, SiteConfig::$dbName);
//		$link = mysql_connect(SiteConfig::$dbHost, SiteConfig::$userName, SiteConfig::$userPassword, false, 65536);
		
		
		//Ensure connection was successful
		If(!$link){
			throw new exception("Can't connect to MySQL Server. Errorcode: %s\n", mysqli_connect_error());
		}Else If(mysqli_connect_errno()) {
			throw new exception("Connect failed: %s\n", mysqli_connect_error());
		}Else
//		If(!$link){
//			throw new exception("Can't connect to MySQL Server");
//		}Else

		//Generate the query
		$q = "CALL ".$targetSP."(";
		foreach ($params as $key => $value) {
			$q = $q.$value. ", ";
		}
		$trimIndex = strrpos($q, ","); //Remove additional ','
		$q = substr($q, 0, $trimIndex);
  		$q = $q.");";

  		### DEBUG
//  		throw new exception("DEBUG: ".$q);
  		### DEBUG

		# Send the query
		$returnedRows = array();
		$debug = "";
		if ($result = mysqli_query($link, $q)){
			# Fetch Results
			while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
				# check if nummeric conversion is needed
				foreach ($row as $key => $value) {				
					$temp1 = (int)$value;
					if(strlen(utf8_decode($value))==(strlen(utf8_decode(strval($temp1))))){
						# Perform conversion - Length matches. Value was an int!
						### DEBUG	
//						$debug = $debug.$key."|".(int)$value.", ";
						### DEBUG
						$row[$key] = (int)$value;
					}else{
						# Write any other conversion we might need here
						# For example; Floats?
					}
				}
				### DEBUG
//				var_dump($row);
//				throw new exception("DONE CONVERSION OF KEYS (".$debug.")");
				### DEBUG
				$returnedRows[] = $row;
			}
		}
		if(mysqli_error($link)) echo mysqli_error($link);
		// Destroy the result set and free the memory used for it
		//mysqli_free_result($result);
		// Close the connection
		mysqli_close($link);
		return $returnedRows;
	}

	/**
	 * Returns mysql_real_escape_string'd version of the input array
	 *
	 * @param array $params
	 * @return array
	 */
	public function EscapeParamArray(array $params){
		$escapedParams = array();
		foreach ($params as $value){
			array_push($escapedParams, (mysql_real_escape_string($value)));
		}
		return $escapedParams;
	}

	/**
	 * Get DB Schema Version According To Database
	 *
	 * @return int
	 */
	public function getSchemaVersion(){
		$schemaVersion = $this->querySingle("SELECT SchemaVersion FROM config");
		return $schemaVersion;
	}
}